package com.dankegongyu.lib.common.widget;

import android.content.Context;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.Space;

import java.util.List;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
 * 显示屏幕范围内完整可见的子View，超出的隐藏
 *
 * @author wpq
 * @version 1.0
 */
public class HorizontalWrappedListView extends HorizontalScrollView {

    private static final String TAG = HorizontalWrappedListView.class.getSimpleName();
    private static final String DIVIDER = "divider";

    private LinearLayout mContainer;

    public HorizontalWrappedListView(@NonNull Context context) {
        super(context);
        init(context);
    }

    public HorizontalWrappedListView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public HorizontalWrappedListView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    private void init(@NonNull Context context) {
        setOverScrollMode(OVER_SCROLL_NEVER);
        setHorizontalScrollBarEnabled(false);

        mContainer = new LinearLayout(context);
        mContainer.setOrientation(LinearLayout.HORIZONTAL);
        mContainer.setGravity(Gravity.CENTER_VERTICAL);
        addView(mContainer);
    }

    public void setAdapter(Adapter adapter) {
        if (adapter == null || adapter.getItemCount() <= 0) {
            return;
        }
        mContainer.removeAllViews();
        LinearLayout.LayoutParams lpSpace = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, 1);
        for (int i = 0, size = adapter.getItemCount(); i < size; i++) {
            Item item = adapter.getItem(this, i);
            if (item == null || item.getContentView() == null) {
                continue;
            }
            View contentView = item.getContentView();
            if (contentView.getParent() != null) {
                ((ViewGroup) contentView.getParent()).removeView(contentView);
            }
            addChild(item.getContentView());
            if (i != size - 1) { // 不加最后一个divider
                int spaceDividerWidth = item.getSpaceDividerWidth();
                if (spaceDividerWidth > 0) {
                    Space space = new Space(getContext());
                    space.setTag(DIVIDER + i);
                    lpSpace.width = spaceDividerWidth;
                    addChild(space, lpSpace);
                } else {
                    View dividerView = item.getDividerView();
                    if (dividerView != null) {
                        if (dividerView.getParent() != null) {
                            ((ViewGroup) dividerView.getParent()).removeView(dividerView);
                        }
                        dividerView.setTag(DIVIDER + i);
                        addChild(dividerView);
                    }
                }
            }
        }
    }

    private void addChild(View child) {
        addChild(child, null);
    }

    private void addChild(View child, ViewGroup.LayoutParams params) {
        if (child != null) {
            if (params != null) {
                mContainer.addView(child, params);
            } else {
                mContainer.addView(child);
            }
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        int width = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
        int childCount = mContainer.getChildCount();
        if (childCount > 0) {
            int childWidthTotal = 0;
            int limitIndex = 0;
            for (int i = 0; i < childCount; i++) {
                View child = mContainer.getChildAt(i);
                if (child == null) {
                    continue;
                }
                childWidthTotal += child.getMeasuredWidth();
                if (childWidthTotal > width) {
                    String tag = (String) child.getTag();
                    if (tag != null && tag.contains(DIVIDER)) {
                        limitIndex = i;
                    } else {
                        // 如果当前超出宽度的子View不是divider，那就是contentView，
                        // 这样屏幕范围内完整显示的最后一个子View是divider，需要把这个divider也隐藏
                        limitIndex = i - 1;
                    }
                    break;
                }
            }
            if (limitIndex > 0) {
                for (int i = childCount - 1; i >= limitIndex; i--) {
                    mContainer.removeViewAt(i);
                }
            }
        }
    }

    public static class Item {
        private View contentView;

        private int spaceDividerWidth; // 空白间隔

        @Nullable
        private View dividerView;

        /**
         * divider是空白
         *
         * @param contentView       内容item
         * @param spaceDividerWidth 空白divider宽度
         */
        public Item(View contentView, int spaceDividerWidth) {
            this.contentView = contentView;
            this.spaceDividerWidth = spaceDividerWidth;
        }

        /**
         * divider是具体View，比如 · | / 或图片等
         *
         * @param contentView 内容item
         * @param dividerView dividerView
         */
        public Item(View contentView, @Nullable View dividerView) {
            this.contentView = contentView;
            this.dividerView = dividerView;
        }

        public View getContentView() {
            return contentView;
        }

        public int getSpaceDividerWidth() {
            return spaceDividerWidth;
        }

        @Nullable
        public View getDividerView() {
            return dividerView;
        }
    }

    public static abstract class Adapter<T> {

        private List<T> mList;

        public Adapter(List<T> data) {
            this.mList = data;
        }

        @Nullable
        public List<T> getData() {
            return mList;
        }

        @Nullable
        public final Item getItem(@NonNull HorizontalWrappedListView parent, int position) {
            T itemData = getItemData(position);
            if (itemData != null) {
                return getItem(parent, position, itemData);
            }
            return null;
        }

        public abstract Item getItem(@NonNull HorizontalWrappedListView parent, int position, @NonNull T itemData);

        @Nullable
        public T getItemData(int position) {
            if (position >= 0 && position < getItemCount()) {
                return mList.get(position);
            }
            return null;
        }

        public int getItemCount() {
            return mList != null ? mList.size() : 0;
        }
    }
}
